<?php

namespace app\common\service;

use app\admin\dao\AccountBillDao;
use app\common\model\AccountBill;

/**
 * 账户资金记录
 * Class AccountBillService
 * @package app\common\service
 */
class AccountBillService
{

    private AccountBillDao $flowDao;

    public function __construct(AccountBillDao $flowDao)
    {
        $this->flowDao = $flowDao;
    }

    // ******************* 付款 *******************

    /**
     * 付款（用户->平台）
     * @param $memberId
     * @param $memberBeforeMoney
     * @param $systemBeforeMoney
     * @param $accountType
     * @param $money
     * @param $billType
     * @param $desc
     * @param $proxyUserPersonnelId
     * @param $proxyMemberId
     * @param $tradeId
     * @param $cashId
     * @return AccountBill
     */
    public function insertPay($fromType, $memberId, $memberBeforeMoney, $systemBeforeMoney, $accountType, $money, $billType, $desc, $proxyUserPersonnelId, $proxyMemberId, $tradeId, $cashId): AccountBill
    {
        $from = [
            'fromType' => $fromType,
            'fromMemberId' => $memberId,
            'fromAccountNumber' => $memberId,
            'fromBeforeMoney' => $memberBeforeMoney,
            // 被代付信息
            'proxyUserPersonnelId' => $proxyUserPersonnelId,
            'proxyMemberId' => $proxyMemberId,
        ];

        $to = [
            'toType' => 'system',
            'toMemberId' => '1',
            'toAccountNumber' => '1',
            'toBeforeMoney' => $systemBeforeMoney,
        ];

        $type = 'pay';

        $attach = [
            'tradeId' => $tradeId,
            'cashId' => $cashId,
            'transactionId' => '0',
        ];

        return $this->insertFlow($from, $to, $accountType, $money, $type, $billType, $desc, $attach);
    }

    /**
     * 三方支付账单（用户->平台）
     * @param $memberId
     * @param $accountNumber
     * @param $accountType
     * @param $money
     * @param $billType
     * @param $desc
     * @param $tradeId
     * @return AccountBill
     */
    public function insertPayThird($memberId, $accountNumber, $accountType, $money, $billType, $desc, $tradeId): AccountBill
    {

        $from = [
            'fromType' => 'member',
            'fromMemberId' => $memberId,
            'fromAccountNumber' => $accountNumber,
        ];

        $to = [
            'toType' => 'system',
            'toMemberId' => '1',
            'toAccountNumber' => '1',
        ];

        $type = 'pay';

        $attach = [
            'tradeId' => $tradeId,
            'cashId' => '0',
            'transactionId' => '0',
        ];

        return $this->insertFlow($from, $to, $accountType, $money, $type, $billType, $desc, $attach);
    }

    // ******************* 退款 *******************

    /**
     * 退款（平台->用户）
     * @param $memberId
     * @param $memberBeforeMoney
     * @param $systemBeforeMoney
     * @param $accountType
     * @param $money
     * @param $billType
     * @param $desc
     * @param $tradeId
     * @param $cashId
     * @param $sourceId
     * @return AccountBill
     */
    public function insertRefund($toType, $memberId, $memberBeforeMoney, $systemBeforeMoney, $accountType, $money, $billType, $desc, $tradeId, $cashId, $sourceId): AccountBill
    {
        $from = [
            'fromType' => 'system',
            'fromMemberId' => '1',
            'fromAccountNumber' => '1',
            'fromBeforeMoney' => $systemBeforeMoney,
        ];

        $to = [
            'toType' => $toType,
            'toMemberId' => $memberId,
            'toAccountNumber' => $memberId,
            'toBeforeMoney' => $memberBeforeMoney,
        ];

        $type = 'refund';

        $attach = [
            'tradeId' => $tradeId,
            'cashId' => $cashId,
            'sourceId' => $sourceId,
        ];

        return $this->insertFlow($from, $to, $accountType, $money, $type, $billType, $desc, $attach);
    }

    /**
     * 三方支付退款账单（平台->用户）
     * @param $memberId
     * @param $accountNumber
     * @param $accountType
     * @param $money
     * @param $billType
     * @param $desc
     * @param $tradeId
     * @param $sourceId
     * @return AccountBill
     */
    public function insertRefundThird($memberId, $accountNumber, $accountType, $money, $billType, $desc, $tradeId, $sourceId): AccountBill
    {
        $from = [
            'fromType' => 'system',
            'fromMemberId' => '1',
            'fromAccountNumber' => '1',
        ];

        $to = [
            'toType' => 'member',
            'toMemberId' => $memberId,
            'toAccountNumber' => $accountNumber,
        ];

        $type = 'refund';

        $attach = [
            'tradeId' => $tradeId,
            'sourceId' => $sourceId,
        ];

        return $this->insertFlow($from, $to, $accountType, $money, $type, $billType, $desc, $attach);
    }

    // ******************* 转账 *******************

    /**
     * 转账（平台<=>用户,公司）
     * @param bool $direction 0平台转出 1平台转入
     * @param $memberType
     * @param $memberId
     * @param $memberBeforeMoney
     * @param $systemBeforeMoney
     * @param $accountType
     * @param $money
     * @param $billType
     * @param $desc
     * @param $transferId
     * @return AccountBill
     */
    public function insertTransfer(bool $direction, $memberType, $memberId, $memberBeforeMoney, $systemBeforeMoney, $accountType, $money, $billType, $desc, $transferId): AccountBill
    {
        if ($direction) {

            $from = ['fromType' => $memberType, 'fromMemberId' => $memberId, 'fromAccountNumber' => $memberId, 'fromBeforeMoney' => $memberBeforeMoney,];

            $to = ['toType' => 'system', 'toMemberId' => '1', 'toAccountNumber' => '1', 'toBeforeMoney' => $systemBeforeMoney,];

        } else {

            $from = ['fromType' => 'system', 'fromMemberId' => '1', 'fromAccountNumber' => '1', 'fromBeforeMoney' => $systemBeforeMoney,];

            $to = ['toType' => $memberType, 'toMemberId' => $memberId, 'toAccountNumber' => $memberId, 'toBeforeMoney' => $memberBeforeMoney,];
        }

        $type = 'transfer';

        $attach = [
            'transferId' => $transferId,
            'cashId' => '0',
            'transactionId' => '0',
        ];

        return $this->insertFlow($from, $to, $accountType, $money, $type, $billType, $desc, $attach);
    }

    /**
     * 三方支付转账账单（平台<=>用户,公司）
     * @param bool $direction 0平台转出 1平台转入
     * @param $memberType
     * @param $memberId
     * @param $accountNumber
     * @param $accountType
     * @param $money
     * @param $billType
     * @param $desc
     * @param $transferId
     * @param $cashId
     * @return AccountBill
     */
    public function insertTransferThird(bool $direction, $memberType, $memberId, $accountNumber, $accountType, $money, $billType, $desc, $transferId, $cashId): AccountBill
    {

        if ($direction) {

            $from = ['fromType' => $memberType, 'fromMemberId' => $memberId, 'fromAccountNumber' => $accountNumber,];

            $to = ['toType' => 'system', 'toMemberId' => '1', 'toAccountNumber' => '1',];

        } else {

            $from = ['fromType' => 'system', 'fromMemberId' => '1', 'fromAccountNumber' => '1',];

            $to = ['toType' => $memberType, 'toMemberId' => $memberId, 'toAccountNumber' => $accountNumber,];
        }


        $type = 'transfer';

        $attach = [
            'transferId' => $transferId,
            'cashId' => $cashId,
            'transactionId' => '0',
        ];

        return $this->insertFlow($from, $to, $accountType, $money, $type, $billType, $desc, $attach);
    }

    /**
     * 线下转账（平台<=>用户,公司）
     * @param bool $direction
     * @param $memberType
     * @param $memberId
     * @param $money
     * @param $billType
     * @param $desc
     * @param $transactionId
     * @return AccountBill
     */
    public function insertTransferOffline(bool $direction, $memberType, $memberId, $money, $billType, $desc, $transactionId): AccountBill
    {

        if ($direction) {

            $from = ['fromType' => $memberType, 'fromMemberId' => $memberId, 'fromAccountNumber' => $memberId,];

            $to = ['toType' => 'system', 'toMemberId' => '1', 'toAccountNumber' => '1',];

        } else {

            $from = ['fromType' => 'system', 'fromMemberId' => '1', 'fromAccountNumber' => '1',];

            $to = ['toType' => $memberType, 'toMemberId' => $memberId, 'toAccountNumber' => $memberId,];
        }


        $accountType = PAYMENT_OFFLINE;

        $type = 'transfer';

        $attach = [
            'transactionId' => $transactionId,
            'transferId' => '0',
            'cashId' => '0',
        ];

        return $this->insertFlow($from, $to, $accountType, $money, $type, $billType, $desc, $attach);
    }


    /**
     * 插入数据
     * @param array $from
     * @param array $to
     * @param $accountType
     * @param $money
     * @param $type
     * @param $billType
     * @param $desc
     * @param array $attach
     * @return AccountBill
     */
    private function insertFlow(array $from, array $to, $accountType, $money, $type, $billType, $desc, array $attach): AccountBill
    {
        // 4舍5入为两位小数
        $money = round($money, 2);

        if (isset($from['fromBeforeMoney']) && is_numeric($from['fromBeforeMoney'])) {
            $from['fromAfterMoney'] = bcsub($from['fromBeforeMoney'], $money, 2);
        }

        if (isset($to['toBeforeMoney']) && is_numeric($to['toBeforeMoney'])) {
            $to['toAfterMoney'] = bcadd($to['toBeforeMoney'], $money, 2);
        }

        $params = [
            'accountType' => $accountType,
            'money' => $money,
            'type' => $type,
            'billType' => $billType,
            'desc' => $desc,
            'tradeId' => $attach['tradeId'] ?? null,
            'transferId' => $attach['transferId'] ?? null,
            'cashId' => $attach['cashId'] ?? null,
            'sourceId' => $attach['sourceId'] ?? null,
        ];

        $params = array_merge($params, $from, $to);

        return $this->flowDao->insertActive($params);
    }
}
